//
// Created by xd on 2020/4/17.
//
#include "cn_study_aviplayer_NativeWindowPlayerActivity.h"

extern "C" {
#include  "avilib/avilib.h"
}

#include <android/native_window.h>
#include <android/native_window_jni.h>
#include "Common.h"


extern "C"
JNIEXPORT void JNICALL
Java_cn_study_aviplayer_NativeWindowPlayerActivity_init(JNIEnv *env, jclass clazz, jlong avi,
                                                        jobject surface) {

    //从surface中获取原生window
    ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);
    if (0 == nativeWindow) {

        ThrowException(env, "java/io/RuntimeException", "不能都获取window");
        goto exit;
    }
    //设置buffer大小为avi视频帧的分辨率
    //如果和window的物理大小不一致
    //buffer会被缩放来匹配这个大小
    if (0 > ANativeWindow_setBuffersGeometry(nativeWindow, AVI_video_width((avi_t *) avi),
                                             AVI_video_height((avi_t *) avi),
                                             WINDOW_FORMAT_RGB_565)) {

        ThrowException(env, "java/io/RuntimeException", "不能够设置buffers");
        nativeWindow = 0;
    }

    exit:
    return;

}


extern "C"
JNIEXPORT jboolean JNICALL
Java_cn_study_aviplayer_NativeWindowPlayerActivity_render(JNIEnv *env, jclass clazz, jlong avi,
                                                          jobject surface) {

    jboolean isFrameRead = JNI_FALSE;

    long frameSize = 0;
    int keyFrame = 0;

    ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);
    if (0 == nativeWindow) {
        ThrowException(env, "java/io/RuntimeException", "不能够获取window");
        goto exit;
    }

    //锁定原生window并访问原始buffer
    ANativeWindow_Buffer windowBuffer;
    if (0 > ANativeWindow_lock(nativeWindow, &windowBuffer, 0)) {

        ThrowException(env, "java/io/RuntimeException", "不能锁住window");
        goto release;
    }
    //将avi帧的比特流读至原始缓冲区
    frameSize = AVI_read_frame((avi_t *) avi, (char *) windowBuffer.bits, &keyFrame);

    //是否读取成功
    if (0 < frameSize) {

        isFrameRead = JNI_TRUE;
    }

    //解锁并且输出缓冲区来显示
    if (0 > ANativeWindow_unlockAndPost(nativeWindow)) {

        ThrowException(env, "java/io/RuntimeException", "不能够解锁window");
        goto release;
    }

    release:
    ANativeWindow_release(nativeWindow);
    nativeWindow = 0;
    exit:
    return isFrameRead;

}


